package com.xwaiy.xwaiyrpc.serializer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xwaiy.xwaiyrpc.model.RpcRequest;
import com.xwaiy.xwaiyrpc.model.RpcResponse;

import java.io.IOException;

/**
 * JSON 序列化器
 * @Author Xwaiy
 * @Date 2025/8/25 15:50
 **/
public class JsonSerializer implements Serializer {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Override
    public byte[] serialize(Object obj) throws IOException {
        return OBJECT_MAPPER.writeValueAsBytes(obj);
    }

    @Override
    public <T> T deserialize(byte[] bytes, Class<T> clazz) throws IOException {
        T obj = OBJECT_MAPPER.readValue(bytes,clazz);
        if(obj instanceof RpcRequest) {
            return handleRequest((RpcRequest) obj,clazz);
        }
        if(obj instanceof RpcResponse) {
            return handleResponse((RpcResponse) obj,clazz);
        }
        return obj;
    }

    /**
     * 特殊处理
     * 反序列化时Object会被作为LinkedHashMap
     * @param request
     * @param type
     * @return
     * @param <T>
     * @throws IOException
     */
    private <T> T handleRequest(RpcRequest request, Class<T> type) throws IOException {
        Class<?>[] paramTypes = request.getParamTypes();
        Object[] params = request.getParams();

        // 循环处理每一个参数类型
        for (int i = 0; i < paramTypes.length; i++) {
            Class<?> clazz = paramTypes[i];
            // TO 如果不同，则下一个
            if(!clazz.isAssignableFrom(params[i].getClass())){
                byte[] paramBytes = OBJECT_MAPPER.writeValueAsBytes(params[i]);
                params[i] = OBJECT_MAPPER.readValue(paramBytes,clazz);
            }
        }

        return type.cast(request);

    }

    private <T> T handleResponse(RpcResponse response, Class<T> type) throws IOException {
        byte[] dataTypes = OBJECT_MAPPER.writeValueAsBytes(response.getData());
        response.setData(OBJECT_MAPPER.readValue(dataTypes,response.getDataType()));
        return type.cast(response);
    }
}
